package com.recource.interceptor;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.recource.annonation.Login;
import com.recource.dao.DesignSelectDao;
import com.recource.domain.DesignSelect;
import com.recource.domain.User;
import com.recource.util.HostHolder;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author yujie
 * @createTime 2023/1/5 15:25
 * @description
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private HostHolder hostHolder;

    @Autowired
    private DesignSelectDao designSelectDao;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(handler instanceof HandlerMethod){
            HandlerMethod handlerMethod = (HandlerMethod)handler;
            Class<?> clazz = handlerMethod.getBeanType();
            if(clazz.isAnnotationPresent(Login.class) || handlerMethod.getMethod().isAnnotationPresent(Login.class)){
                if(Objects.isNull(request.getCookies())){
                    response.sendRedirect(request.getContextPath()+"/login.html");
                    return false;
                }
                List<Cookie> cookies = Arrays.asList(request.getCookies());
                List<String> cookieNames = cookies.stream().map(Cookie::getName).collect(Collectors.toList());
                if(!CollectionUtils.contains( cookieNames.iterator(), "token")){
                    response.sendRedirect(request.getContextPath()+"/login.html");
                    return false;
                }
                Map<String, String> map = new HashMap<>();
                cookies.forEach(cookie -> {
                    map.put(cookie.getName(), cookie.getValue());
                });
                String sessionId = map.get("token");
                if(StringUtils.isEmpty(sessionId)){
                    response.sendRedirect(request.getContextPath()+"/login.html");
                    return false;
                }
                Object attribute = request.getSession().getAttribute(sessionId);
                if(Objects.nonNull(attribute) && attribute instanceof User){
                    User user = (User) attribute;
                    LambdaQueryWrapper<DesignSelect> designSelectLambdaQueryWrapper = new LambdaQueryWrapper<>();
                    designSelectLambdaQueryWrapper.eq(DesignSelect::getUid, user.getId());
                    DesignSelect designSelect = designSelectDao.selectOne(designSelectLambdaQueryWrapper);
                    if(Objects.nonNull(designSelect)){
                        user.setFlag(true);
                        user.setDid(designSelect.getDid());
                    }
                    hostHolder.setUser(user);
                    return true;
                }else{
                    response.sendRedirect(request.getContextPath()+"/login.html");
                    return false;
                }
            }else{
                //TODO 不需要登录的修改
                Map<String, String> map = new HashMap<>();
                Cookie[] cookies = request.getCookies();
                if(Objects.nonNull(cookies)){
                    for (Cookie cookie : cookies) {
                        map.put(cookie.getName(), cookie.getValue());
                    }
                    String token = map.get("token");
                    if(StringUtils.isNotEmpty(token)){
                        Object attribute = request.getSession().getAttribute(token);
                        if(Objects.nonNull(attribute) && attribute instanceof User){
                            User user = (User) attribute;
                            LambdaQueryWrapper<DesignSelect> designSelectLambdaQueryWrapper = new LambdaQueryWrapper<>();
                            designSelectLambdaQueryWrapper.eq(DesignSelect::getUid, user.getId());
                            DesignSelect designSelect = designSelectDao.selectOne(designSelectLambdaQueryWrapper);
                            if(Objects.nonNull(designSelect)){
                                user.setFlag(true);
                                user.setDid(designSelect.getDid());
                            }
                            hostHolder.setUser(user);
                        }
                    }
                }
                return true;
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        User user = hostHolder.getUser();
        if(user != null && modelAndView != null){
            modelAndView.addObject("loginUser",user);
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        hostHolder.clear();
    }
}
